<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Shop\View;

use Admin\Data\Common;
use Admin\Data\Config;
use Cms\Entity\CmsClass;
use Cms\Entity\SingleCms;
use Doctrine\ORM\EntityManager;
use Extend\Entity\Navigation;
use Goods\Entity\Goods;
use Goods\Entity\GoodsClass;
use Goods\Entity\GoodsInClass;
use Laminas\Config\Factory;
use Laminas\Math\Rand;
use Laminas\Mvc\I18n\Translator;
use Laminas\Session\Container;
use Laminas\View\Helper\AbstractHelper;
use Laminas\View\Helper\ServerUrl;
use Operation\Entity\Ad;
use Operation\Entity\AdSlide;
use PHPQRCode\QRcode;
use Sales\Data\OrderState;
use Sales\Entity\Order;
use Sales\Entity\OrderGoods;
use User\Entity\Cart;
use User\Entity\UserGoodsFavorites;

class ShopHelper extends AbstractHelper
{
    private $translator;
    private $request;
    private $sessionUser;
    private $dbshopSession;
    private $routeMatch;
    private $entityManager;
    private $csrfValue = '';

    private $goodsImageDefault;
    private $classImageDefault;
    private $brandLogoDefault;
    private $orderConfig;

    public function __construct(
        Translator  $translator,
        $request,
        $routeMatch,
        EntityManager   $entityManager
    )
    {
        $this->translator   = $translator;
        $this->request      = $request;
        $this->routeMatch   = $routeMatch;
        $this->entityManager= $entityManager;

        if($this->sessionUser == null) $this->sessionUser = new Container('dbshopUser');
        if($this->dbshopSession == null) $this->dbshopSession = new Container('dbshopSession');
    }

    /**
     * 检测会员是否登录
     * @return bool
     */
    public function checkUserLoginStatus()
    {
        return $this->sessionUser->offsetExists('user_id');
    }

    /**
     * 获取会员登录信息
     * @param $key
     * @return mixed|null
     */
    public function getUserLoginData($key)
    {
        return $this->getView()->escapeHtml($this->sessionUser->offsetGet($key));
    }

    /**
     * 获取shop通用的 session 信息
     * @param $key
     * @return mixed|string|null
     */
    public function getDbshopSessionData($key)
    {
        return $this->dbshopSession->offsetExists($key) ? $this->dbshopSession->offsetGet($key) : '';
    }

    /**
     * 商品详情的上一页
     * @param $url
     * @return mixed|null
     */
    public function goodsPreviousPage($url)
    {
        $previousPage = $this->request->getServer()->get('HTTP_REFERER');
        if (!empty($previousPage) && stripos($previousPage, 'shop-goods') === false) $this->dbshopSession->offsetSet('goodsPreviousPage', $previousPage);

        return $this->dbshopSession->offsetExists('goodsPreviousPage') ? $this->dbshopSession->offsetGet('goodsPreviousPage') : $url;
    }

    /**
     * 获取信息
     * @return array|\Laminas\Config\Config|mixed|string
     */
    public function getDbshopArray()
    {
        return Common::dbshopJson();
    }

    /**
     * 获取导航信息
     * @param $type 1 顶部，2 中部，3 底部
     * @return array|object[]
     */
    public function shopNavigationMenu($type)
    {
        return $this->entityManager->getRepository(Navigation::class)->findBy(['navigationPlace' => $type], ['navigationSort' => 'ASC']);
    }

    /**
     * 获取手机验证码时间间隔
     * @return int
     */
    public function getPhoneCaptchaSecond()
    {
        return Config::PHONE_CAPTCHA_EXPIRED_SECOND;
    }

    /**
     * 订单状态
     * @param $orderStatus
     * @return mixed
     */
    public function getOrderStatus($orderStatus)
    {
        return Common::orderStatus($this->translator)[$orderStatus];
    }

    /**
     * 余额提现状态
     * @param $state
     * @return mixed
     */
    public function getWithdrawState($state)
    {
        return Common::withdrawState($this->translator)[$state];
    }

    /**
     * 订单状态编码
     * @param $statusStr
     * @return mixed
     */
    public function getOrderStatusCode($statusStr)
    {
        return Common::orderStatusCode($statusStr);
    }

    /**
     * 积分类型
     * @param $typeId
     * @return mixed
     */
    public function userIntegralType($typeId)
    {
        $integralType = Common::integralType($this->translator);

        return $integralType[$typeId];
    }

    /**
     * 订单支付类型名称
     * @param $typeCode
     * @return mixed
     */
    public function getPaymentTypeName($typeCode)
    {
        return Common::paymentTypeName($typeCode, $this->translator);
    }

    /**
     * 订单配送类型名称
     * @param $typeCode
     * @return mixed
     */
    public function getDeliveryTypeName($typeCode)
    {
        return Common::deliveryTypeName($typeCode, $this->translator);
    }

    /**
     * 订单配送轨迹状态
     * @return mixed|string[]|null
     */
    public function getDeliveryTrackState()
    {
        return Common::configValue('deliveryApiState', 'delivery');
    }

    /**
     * 获取国际电话区号
     * @param $areaCode
     * @return int
     */
    public function shopAreaPhoneCode($areaCode)
    {
        return '+'.Common::areaPhoneCode($areaCode);
    }

    /**
     * 加入订单后的价格无需转换，已经对应固定货币的价格信息（包括但不限于 订单、充值等）
     * @param $number
     * @param $symbol
     * @return string
     */
    public function orderCurrency($number, $symbol)
    {
        return $symbol . $number;
    }

    /**
     * 可兑换商品的消费积分数
     * @param $goodsPrice
     * @return float|int
     */
    public function getGoodsIntegral($goodsPrice)
    {
        if($this->checkUserLoginStatus() == null && Common::configValue('goods', 'config')['login_goods_price_show'] == 1) return $this->translator->translate('登录可见');

        return Common::calculation($goodsPrice * Common::configValue('integral_type_1', 'integral')['integralCurrencyCon'], 100, '*');
    }

    /**
     * 购物车商品数量
     * @return int
     */
    public function getShopCartGoodsNum()
    {
        return $this->getUserCartCount();
    }

    /**
     * 获取客户购物车数量
     * @return int
     */
    public function getUserCartCount()
    {
        if(!$this->sessionUser->offsetExists('user_id')) return 0;

        return $this->entityManager->getRepository(Cart::class)->count(['userId' => $this->sessionUser->offsetGet('user_id'), 'buyNow' =>0]);
    }

    /**
     * 获取客户购物车商品列表
     * @return int|mixed|string|null
     */
    public function getUserCartGoodsList()
    {
        return $this->entityManager->getRepository(Cart::class)->shopCartGoodsList($this->sessionUser->offsetGet('user_id'));
    }

    /**
     * 获取商品收藏状态
     * @param $goodsId
     * @return bool|object|null
     */
    public function getGoodsFavoritesStatus($goodsId)
    {
        if(!$this->sessionUser->offsetExists('user_id')) return false;
        return $this->entityManager->getRepository(UserGoodsFavorites::class)->findOneBy(['goodsId' => $goodsId, 'userId' => $this->sessionUser->offsetGet('user_id')]);
    }

    /**
     * 会员获取的商品收藏数组
     * @return array
     */
    public function getUserGoodsFavoritesArray()
    {
        if(!$this->sessionUser->offsetExists('user_id')) return [];

        $favoritesArray = [];
        $favoritesList  = $this->entityManager->getRepository(UserGoodsFavorites::class)->findBy(['userId' => $this->sessionUser->offsetGet('user_id')]);
        if ($favoritesList) foreach ($favoritesList as $value) {
            $favoritesArray[] = $value->getGoodsId();
        }

        return $favoritesArray;
    }

    /**
     * 会员的商品收藏数量
     * @return int
     */
    public function getUserGoodsFavoritesNum()
    {
        if (!$this->sessionUser->offsetExists('user_id')) return 0;
        return $this->entityManager->getRepository(UserGoodsFavorites::class)->count(['userId' => $this->sessionUser->offsetGet('user_id')]);
    }

    /**
     * 客户设置
     * @param $name
     * @param string $configFile
     * @return mixed|string[]|null
     */
    public function customer($name, string $configFile = 'customer')
    {
        return Common::configValue($name, $configFile);
    }

    /**
     * 系统设置地图状态
     * @param $name
     * @return mixed|string[]|null
     */
    public function mapConfig($name)
    {
        return Common::configValue($name, 'config');
    }

    /**
     * 自提点地图状态
     * @param $name
     * @return bool
     */
    public function selfLocationMapState($name)
    {
        $mapConfig = Common::configValue($name, 'config');
        if (
            empty($mapConfig['map_key'])
            || !isset($mapConfig['map_state'])
            || $mapConfig['map_state'] != 1
            || !isset($mapConfig['self_location_map_state'])
            || $mapConfig['self_location_map_state'] != 1) return false;
        return true;
    }

    /**
     * 收货地址地图状态
     * @param $name
     * @param string $type
     * @return bool
     */
    public static function addressMapState($name, string $type = 'pc')
    {
        $typeArray = ['pc' => 'address_map_state', 'phone' => 'address_phone_map_state'];

        $mapConfig = Common::configValue($name, 'config');
        if (
            empty($mapConfig['map_key'])
            || !isset($mapConfig['map_state'])
            || $mapConfig['map_state'] != 1
            || !isset($mapConfig[$typeArray[$type]])
            || $mapConfig[$typeArray[$type]] != 1) return false;

        return true;
    }

    /**
     * 获取商城系统中的配置信息
     * @param $name
     * @param string $type
     * @param string $configFile
     * @return mixed
     */
    public function shop($name, $type = 'base', $configFile = 'config')
    {
        return Common::configValue($type, $configFile)[$name] ?? null;
    }

    /**
     * 前台底部图片
     * @return mixed|string[]|null
     */
    public function shopFooterImage()
    {
        return Common::configValue('shop_footer', 'config');
    }

    /**
     * 获取商城的热门关键词
     * @return array
     */
    public function shopHotKeywords()
    {
        return array_filter(explode('|', Common::configValue('base', 'config')['shop_hot_keywords']));
    }

    /**
     * 前台货币
     * @return array|\Laminas\Config\Config|mixed
     */
    public function shopCurrency()
    {
        $currencyArray = Common::readConfigFile('currency');
        if($this->dbshopSession->offsetGet('currencyCode') && $currencyArray[$this->dbshopSession->offsetGet('currencyCode')]['state'] == 1) {
            $currencyArray['default'] = $currencyArray[$this->dbshopSession->offsetGet('currencyCode')];
        }
        if (count($currencyArray) > 2) foreach ($currencyArray as $key => $value) {
            if ($value['state'] != 1) unset($currencyArray[$key]);
        }

        return $currencyArray;
    }

    /**
     * 会员名称中间用星号代替
     * @param $userName
     * @return string
     */
    public function userNameHide($userName)
    {
        return Common::stringHide($userName);
    }

    /**
     * 有货显示
     * @param $stockShow
     * @return mixed
     */
    public function goodsStockShow($stockShow)
    {
        return Common::goodsStockShow($this->translator)[$stockShow];
    }

    /**
     * 缺货显示
     * @param $outStockShow
     * @return mixed
     */
    public function goodsOutStockShow($outStockShow)
    {
        return Common::goodsOutStockShow($this->translator)[$outStockShow];
    }

    /**
     * 广告图片路径
     * @param $adFile
     * @return mixed
     */
    public function baseAdImagePath($adFile)
    {
        $adFile = Common::shopImageOss($adFile, 'ad');
        return substr($adFile,0, 4) == 'http' ? $adFile : Common::shopImageSpeed($this->getView()->basePath($adFile), 'ad');
    }

    /**
     * css文件路径
     * @param $cssFile
     * @return mixed
     */
    public function baseCssPath($cssFile)
    {
        return substr($cssFile,0, 4) == 'http' ? $cssFile : $this->getView()->basePath($cssFile);
    }

    /**
     * js文件路径
     * @param $jsFile
     * @return mixed
     */
    public function baseJsPath($jsFile)
    {
        return substr($jsFile,0, 4) == 'http' ? $jsFile : $this->getView()->basePath($jsFile);
    }

    /**
     * css 模板图片 路径
     * @param $imageFile
     * @return mixed
     */
    public function baseImagePath($imageFile)
    {
        return substr($imageFile,0, 4) == 'http' ? $imageFile : $this->getView()->basePath($imageFile);
    }

    /**
     * 会员头像路径
     * @param $avatarFile
     * @return mixed
     */
    public function userAvatarImagePath($avatarFile)
    {
        if(empty($avatarFile)) return $this->getView()->basePath(Common::configValue('default_user_avatar', 'customer')) . '?v=' . time();
        $avatarFile = Common::shopImageOss($avatarFile, 'avatar');
        return substr($avatarFile,0, 4) == 'http' ? $avatarFile : Common::shopImageSpeed($this->getView()->basePath($avatarFile), 'avatar');
    }

    /**
     * 商品图片路径
     * @param $goodsImageFile
     * @param bool $urlStatus
     * @return string
     */
    public function baseGoodsImagePath($goodsImageFile, $urlStatus = false)
    {
        //如为空，则返回默认图片
        if(empty($goodsImageFile)) {
            if ($this->goodsImageDefault == null) $this->goodsImageDefault = Common::configValue('goods_image_default', 'upload');
            return ($urlStatus ? $this->getView()->url('shop', [], ['force_canonical' => true]) . $this->goodsImageDefault : $this->getView()->basePath($this->goodsImageDefault)) . '?v=' . time();
        }
        $goodsImageFile = Common::shopImageOss($goodsImageFile, 'goods');
        return substr($goodsImageFile,0, 4) == 'http' ? $goodsImageFile : ($urlStatus ? $this->getView()->url('shop', [], ['force_canonical' => true]) . $goodsImageFile : Common::shopImageSpeed($this->getView()->basePath($goodsImageFile), 'goods'));
    }

    /**
     * 商品分类图片路径
     * @param $classImageFile
     * @return mixed
     */
    public function baseGoodsClassImagePath($classImageFile)
    {
        //如为空，则返回默认图片
        if(empty($classImageFile)) {
            if ($this->classImageDefault == null) $this->classImageDefault = Common::configValue('class_image_default', 'upload');
            return $this->getView()->basePath($this->classImageDefault) . '?v=' . time();
        }
        $classImageFile = Common::shopImageOss($classImageFile, 'goodsClass');
        return substr($classImageFile,0, 4) == 'http' ? $classImageFile : Common::shopImageSpeed($this->getView()->basePath($classImageFile), 'goodsClass');
    }

    /**
     * 商品品牌图片路径
     * @param $brandImageFile
     * @return mixed
     */
    public function baseGoodsBrandImagePath($brandImageFile)
    {
        //如为空，则返回默认图片
        if(empty($brandImageFile)) {
            if ($this->brandLogoDefault == null) $this->brandLogoDefault = Common::configValue('brand_logo_default', 'upload');
            return $this->getView()->basePath($this->brandLogoDefault) . '?v=' . time();
        }
        $brandImageFile = Common::shopImageOss($brandImageFile, 'goodsBrand');
        return substr($brandImageFile,0, 4) == 'http' ? $brandImageFile : Common::shopImageSpeed($this->getView()->basePath($brandImageFile), 'goodsBrand');
    }

    /**
     * 附件或文件路径
     * @param $file
     * @return mixed
     */
    public function baseFilePath($file)
    {
        return substr($file,0, 4) == 'http' ? $file : $this->getView()->basePath($file);
    }

    /**
     * 对详情内容进行处理
     * @param $body
     * @param $type
     * @return array|string|string[]|null
     */
    public function shopBody($body, $type)
    {
        $body = Common::shopBody($body, $type);

        if ($type != 'goods') {//对非商品详情内容，进行解析查看其内是否有商品信息调用
            $goodsIdArray = [];
            preg_match_all("/{goods-(.*)}/U", $body, $goodsIdArray);
            if (is_array($goodsIdArray[1]) && !empty($goodsIdArray[1])) {
                $patterns       = [];
                $replacements   = [];
                foreach ($goodsIdArray[1] as $goodsId) {
                    $patterns[]     = '{goods-'.$goodsId.'}';
                    $replacements[] = Common::httpGet($this->getView()->url('shop-goods', ['action' => 'getInsertEditorGoods'], ['query' => ['goodsId' => $goodsId], 'force_canonical' => true]));
                }

                if (!empty($replacements)) return str_replace($patterns, $replacements, $body);
            }
        }

        return $body;
    }

    /**
     * 获取扩展的url信息
     * @return array|\Laminas\Config\Config
     */
    public function extendShopUrlArray()
    {
        if (file_exists('data/moduleData/Plugin/shopUrl.ini')) return Factory::fromFile('data/moduleData/Plugin/shopUrl.ini');
        return [];
    }

    /**
     * 判断是否为手机状态
     * @return bool
     */
    public function isMobile()
    {
        return Common::isMobile();
    }

    /**
     * 获取客服代码
     * @return string[]
     */
    public function getOnlineService()
    {
        $array = ['long' => '', 'online' => []];

        $onlineService = Common::readConfigFile('onlineService');
        if (empty($onlineService)) return $array;

        $controller = $this->getController();
        $action     = $this->getAction();

        $client = Common::isMobile() ? 'mobile' : 'pc';
        //珑客服
        if (
            isset($onlineService['onlineBody']['long']['range'])
            && !empty($onlineService['onlineBody']['long']['range'])
            && !empty($onlineService['onlineBody']['long']['content'])
            && in_array($controller.'-'.$action, $onlineService['onlineBody']['long']['range'])
            && (!empty($onlineService['longService']['client']) && in_array($client, $onlineService['longService']['client']))
        ) {
            $array['long'] = $onlineService['onlineBody']['long']['content'];
        }
        //在线客服
        if (
            isset($onlineService['onlineBody']['online'])
            && !empty($onlineService['onlineBody']['online'])
            && (!empty($onlineService['onlineServiceClient']) && in_array($client, $onlineService['onlineServiceClient']))
        ) foreach ($onlineService['onlineBody']['online'] as $onlineValue) {
            if (!empty($onlineValue['range']) && in_array($controller.'-'.$action, $onlineValue['range']) && !empty($onlineValue['content'])) {
                $array['online'][] = $onlineValue['content'];
            }
        }

        return $array;
    }

    /**
     * 随机商品显示
     * @param int $goodsId
     * @param int $num
     * @return mixed
     */
    public function getShopRandGoods(int $goodsId = 0, int $num = 5)
    {
        return $this->entityManager->getRepository(Goods::class)->findShopRandGoods($num, $goodsId, (int) $this->getUserLoginData('user_group_id'));
    }

    /**
     * 获取模块名称
     * @return false|mixed|string
     */
    public function getModule()
    {
        if($this->routeMatch == null) return false;

        $controller = $this->routeMatch->getParam('controller');
        $module     = $this->routeMatch->getParam('__NAMESPACE__');

        $controller = explode('\\', $controller);
        $module     = explode('\\', $module);
        if($module[0] === '' && count($controller) === 3) {
            $module[0] = $controller[0];
        }

        return $module[0];
    }

    /**
     * 获取Controller名称
     * @return bool|mixed
     */
    public function getController()
    {
        if($this->routeMatch == null) return false;

        $controller = $this->routeMatch->getParam('controller');
        $controller = explode('\\', $controller);
        return array_pop($controller);
    }

    /**
     * 获取Action名称
     * @return bool
     */
    public function getAction()
    {
        if($this->routeMatch == null) return false;

        return $this->routeMatch->getParam('action');
    }

    /**
     * 创建get操作的CSRF Token
     * @return mixed|null
     */
    public function getCsrfValue()
    {
        if(empty($this->csrfValue)) {
            $this->dbshopSession->offsetSet('shopQueryToken', md5(time() . Rand::getBytes(32) . 'shopQueryToken'));
            $this->csrfValue = $this->dbshopSession->offsetGet('shopQueryToken');
        }
        return $this->csrfValue;
    }

    /**
     * 返回分页url的Query字符串，去除page
     * @return bool|string
     */
    public function pagesQuery()
    {
        $queryStr = $this->request->getServer()->get('QUERY_STRING');
        if(!empty($queryStr)) {
            if(strpos($queryStr, 'page=') !== false) {
                $num = strpos($queryStr, '&');
                if($num) return substr($queryStr, $num);
                else return '';
            } else return '&'.$queryStr;
        }
        return $queryStr;
    }

    /**
     * 微信分享公众号信息
     * @param $shareUrl
     * @return array|string
     */
    public function getWxSignPackage($shareUrl)
    {
        return Common::getWxSignPackage($shareUrl);
    }

    /**
     * 通用有效时间计算
     * @param $startTime
     * @param $endTime
     * @return string
     */
    public function effectiveTime($startTime, $endTime)
    {
        $iStartTime  = $startTime > 0 ? $this->getView()->dateFormat($startTime, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE, Config::SHOP_DATE_FORMAT) : '';
        $iEndTime    = $endTime > 0 ? $this->getView()->dateFormat($endTime, \IntlDateFormatter::MEDIUM, \IntlDateFormatter::NONE, Config::SHOP_DATE_FORMAT) : '';
        if(empty($iStartTime) && empty($iEndTime)) {
            $startAndEndTime = $this->translator->translate('长期有效');
        } elseif (!empty($iEndTime) && time() > $endTime) {
            $startAndEndTime = '<span style="color: red;">'.$this->translator->translate('已经过期').'</span>';
        } else {
            $startAndEndTime = (empty($iStartTime) ? $this->translator->translate('无') : $iStartTime) . ' / ' . (empty($iEndTime) ? $this->translator->translate('无') : $iEndTime);
        }

        return $startAndEndTime;
    }

    /**
     * 获取指定数量的会员订单信息
     * @param int $num
     * @return mixed
     */
    public function shopOrderListNum($num = 10)
    {
        return $this->entityManager->getRepository(Order::class)->findBy(['userId' => $this->sessionUser->offsetGet('user_id')], ['orderId' => 'DESC'], $num);
    }

    /**
     * 商品分类的breadcrumbs
     * @param $code
     * @param $templateCode
     * @param $classInfo
     * @return array
     */
    public function shopGoodsClassBreadcrumbs($code, $templateCode, $classInfo)
    {
        $classList = $this->entityManager->getRepository(GoodsClass::class)->shopClassBreadcrumbs($classInfo);
        return ['classId' => $classInfo->getClassId(), 'classList' => $classList];
    }

    /**
     * 文章分类的breadcrumbs
     * @param $code
     * @param $templateCode
     * @param $classId
     * @return array
     */
    public function shopCmsClassBreadcrumbs($code, $templateCode, $classId)
    {
        $classInfo = $this->entityManager->getRepository(CmsClass::class)->findOneBy(['cmsClassId' => $classId, 'cmsClassState' => 1]);
        if ($classInfo == null) return [];

        $array = [];
        if ($classInfo->getCmsClassTopId() > 0) {
            $classTopInfo = $this->entityManager->getRepository(CmsClass::class)->findOneBy(['cmsClassId' => $classInfo->getCmsClassTopId(), 'cmsClassState' => 1]);
            if ($classTopInfo) $array[] = ['id' => $classTopInfo->getCmsClassId(), 'title' => $classTopInfo->getCmsClassName()];
        }
        $array[] = ['id' => $classInfo->getCmsClassId(), 'title' => $classInfo->getCmsClassName()];

        return ['classId' => $classId, 'classList' => $array];
    }

    /**
     * 商品分类推荐商品列表
     * @param $code
     * @param $templateCode
     * @param $classId
     * @return array
     */
    public function shopClassRecommendGoods($code, $templateCode, $classId)
    {
        $recommendGoods = $this->entityManager->getRepository(GoodsInClass::class)->shopFindClassRecommendGoods($classId);
        return ['classId' => $classId, 'recommendGoods' => $recommendGoods];
    }

    /**
     * 前台单页文章调用（多个调用）
     * @param $singleTag
     * @param $templateCode
     * @return array
     */
    public function shopMoreSingleCms($singleTag, $templateCode)
    {
        $singleCmsArray = [];
        $singleCmsList  = $this->entityManager->getRepository(SingleCms::class)->findBy(['singleTag' => $singleTag, 'templateCode' => $templateCode], ['singleCmsSort' => 'ASC']);
        if($singleCmsList == null) return $singleCmsArray;

        foreach ($singleCmsList as $item) {
            $singleCmsArray[] = [
                'id'    => $item->getSingleCmsId(),
                'title' => $item->getSingleCmsTitle(),
                'body'  => $item->getSingleCmsBody()
            ];
        }

        return $singleCmsArray;
    }

    /**
     * 前台单页文章调用（单个调用）
     * @param $singleTag
     * @param $templateCode
     * @return array
     */
    public function shopSingleCms($singleTag, $templateCode)
    {
        $singleCmsInfo = $this->entityManager->getRepository(SingleCms::class)->findOneBy(['singleTag' => $singleTag, 'templateCode' => $templateCode]);
        if($singleCmsInfo == null) return [];

        return [
            'id'    => $singleCmsInfo->getSingleCmsId(),
            'title' => $singleCmsInfo->getSingleCmsTitle(),
            'body'  => $singleCmsInfo->getSingleCmsBody()
        ];
    }

    /**
     * 前台广告显示
     * @param $adCode
     * @param $templateCode
     * @return mixed
     */
    public function shopAdShow($adCode, $templateCode)
    {
        $adArray= [];
        $adInfo = $this->entityManager->getRepository(Ad::class)->findOneBy(['adPlaceCode' => $adCode, 'templateCode' => $templateCode, 'adState' => 1]);
        if($adInfo == null) return $adArray;
        if((!empty($adInfo->getAdStartTime()) && $adInfo->getAdStartTime() > time()) || (!empty($adInfo->getAdEndTime()) && $adInfo->getAdEndTime() < time())) return $adArray;

        if($adInfo->getAdType() == 'image') {
            $adArray = [
                'ad_url'    => $adInfo->getAdUrl(),
                'ad_image'  => $adInfo->getAdBody(),
                'ad_words'  => $adInfo->getAdWords()
            ];
        } else {
            $slideImage = $this->entityManager->getRepository(AdSlide::class)->findBy(['adId' => $adInfo->getAdId()], ['adSlideSort' => 'ASC']);
            if($slideImage) foreach ($slideImage as $imageValue) {
                $adArray[] = [
                    'ad_url'    => $imageValue->getAdSlideUrl(),
                    'ad_image'  => $imageValue->getAdSlideImage(),
                    'ad_words'  => $imageValue->getAdWords()
                ];
            }
        }

        return $adArray;
    }
    /**
     * 获取两级的商品分类
     * @return array
     */
    public function secGoodsClass()
    {
        //商品分类
        $goodsClass = $this->entityManager->getRepository(GoodsClass::class)->findBy(['classState' => 1], ['classTopId' => 'ASC', 'classSort' => 'ASC']);
        $classList  = Common::classOptions($goodsClass, 0, 'getClassTopId', 'getClassId', 2);

        $classArray     = [];
        $subClassArray  = [];
        if($classList) foreach ($classList as $classValue) {
            if($classValue->getClassTopId() == 0) $classArray[] = $classValue;
            else $subClassArray[$classValue->getClassTopId()][] = $classValue;
        }

        return ['classArray' => $classArray, 'subClassArray' => $subClassArray];
    }

    /**
     * 获取下级商品分类
     * @param $classTopId
     * @return array|GoodsClass[]|object[]
     */
    public function goodsSubClass($classTopId)
    {
        return $this->entityManager->getRepository(GoodsClass::class)->findBy(['classState' => 1, 'classTopId' => $classTopId], ['classSort' => 'ASC']);
    }

    /**
     * 获取指定位置的区域内容调用
     * @param $location
     * @param int $key
     * @param int $id
     * @return array
     */
    public function helperPartial($location, $key = 0, $id = 0)
    {
        $partial = [];
        $shopDefaultTemplate    = Common::getShopDefaultTemplate();
        $shopDefaultTemplateCode= str_replace('/', '-', $shopDefaultTemplate);
        $config = Factory::fromFile('module/Shop/view/'.$shopDefaultTemplate.'/shop/templatePartial.ini');
        if(isset($config[$location])) {
            if ($key > 0 && $id && isset($config[$location][$key])) {//指定获取带id的信息
                $partial['partialFile'] = $config[$location][$key]['partial'];
                if (isset($config[$location][$key]['functionArg'])) {
                    $partial['partialArg'] = $config[$location][$key]['functionArg'];
                    $partial['partialArg'][$config[$location][$key]['partialBody']] = $this->{$config[$location][$key]['functionName']}($config[$location][$key]['code'], $shopDefaultTemplateCode, $id);
                } else $partial['partialArg'] = [$config[$location][$key]['partialBody'] => $this->{$config[$location][$key]['functionName']}($config[$location][$key]['code'], $shopDefaultTemplateCode, $id)];
            } else {//通用调用
                foreach ($config[$location] as $key => $value) {
                    $partial[$key]['partialFile'] = $value['partial'];
                    if(isset($value['functionArg'])) {
                        $partial[$key]['partialArg'] = $value['functionArg'];
                        $partial[$key]['partialArg'][$value['partialBody']] = $this->{$value['functionName']}($value['code'], $shopDefaultTemplateCode);
                    } else $partial[$key]['partialArg'] = [$value['partialBody'] => $this->{$value['functionName']}($value['code'], $shopDefaultTemplateCode)];
                }
            }
        }

        return $partial;
    }

    /**
     * 生成二维码(商城，商品)
     * @param $text
     * @param $qrCodeType
     * @param $fileName
     * @param false $overwriteFile
     * @return string|string[]
     */
    public function helperCreateQrCodeFile($text, $qrCodeType, $fileName, $overwriteFile = false)
    {
        $filePathArray = [
            'shop' => Config::COMMON_IMAGE_PATH,
            'goods'=> Config::GOODS_QRCODE_IMAGE_PATH,
            ''
        ];
        if (!isset($filePathArray[$qrCodeType])) return '';

        $serverUrl  = new ServerUrl();
        $shopHost   = str_replace('.', '_', $serverUrl->getHost()) . '_';

        //如果是商品的二维码，那么判断是否登录，登录则生成会员专用二维码
        if ($qrCodeType == 'goods') {
            if (!is_dir($filePathArray[$qrCodeType] . intval($fileName))) mkdir($filePathArray[$qrCodeType] . intval($fileName), 0766, true);
            if ($this->checkUserLoginStatus()) {
                $invitationQrCodeFile = $filePathArray[$qrCodeType] . intval($fileName) . '/'. $shopHost . $this->sessionUser->offsetGet('user_id'). '_' . basename($fileName) . '_pc.png';
            } else {
                $invitationQrCodeFile = $filePathArray[$qrCodeType] . intval($fileName) . '/'. $shopHost. basename($fileName) . '_pc.png';
            }
        } else $invitationQrCodeFile = $filePathArray[$qrCodeType] . $shopHost. basename($fileName) . '.png';

        if(!file_exists($invitationQrCodeFile)) QRcode::png($text, $invitationQrCodeFile, 0, 6, 1);
        else {
            if(!$overwriteFile) return str_replace(Config::PUBLIC_PATH, '', $invitationQrCodeFile).'?v='.time();
            else QRcode::png($text, $invitationQrCodeFile, 0, 6, 1);
        }
        return str_replace(Config::PUBLIC_PATH, '', $invitationQrCodeFile).'?v='.time();
    }

    /**
     * 订单付款时，判断是否可以付款
     * @param Order $orderInfo
     * @return bool
     */
    public function shopPayOrder(Order $orderInfo)
    {
        return OrderState::payOrder($orderInfo);
    }

    /**
     * 取消订单，判断是否可以进行处理
     * @param Order $orderInfo
     * @return bool
     */
    public function shopCancelOrder(Order $orderInfo)
    {
        return OrderState::cancelOrder($orderInfo);
    }

    /**
     * 订单收货，判断是否可以进行收货操作
     * @param Order $orderInfo
     * @return bool
     */
    public function shopReceiptOrder(Order $orderInfo)
    {
        return OrderState::receiptOrder($orderInfo);
    }

    /**
     * 物流轨迹，判断是否可查看物流轨迹
     * @param Order $orderInfo
     * @param array $deliveryIdArray
     * @return bool
     */
    public function shopOrderExpressTrack(Order $orderInfo, array $deliveryIdArray = [])
    {
        return OrderState::orderExpressTrack($orderInfo, $deliveryIdArray);
    }

    /**
     * 前台判断客户是否可以对订单商品进行申请售后
     * @param Order $orderInfo
     * @param OrderGoods $orderGoods
     * @return bool
     */
    public function shopOrderGoodsService(Order $orderInfo, OrderGoods $orderGoods)
    {
        if ($this->orderConfig == null) $this->orderConfig = Common::configValue('order', 'config');
        if (
            $orderInfo->getOrderStatus() >= Common::orderStatusCode('GOODS_RECEIVED')
            && $this->orderConfig['order_return'] == 1
            && $orderGoods->getGoodsType() == 1
            && time() < $orderInfo->getOrderFinishTime() + $this->orderConfig['order_return_limit'] * 86400
        ) return true;

        return false;
    }

    /**
     * 字符截取方法
     * @param string $str   要截取的字符串
     * @param int $length   需要截取的长度，0为不截取
     * @param bool $append  是否显示省略号，默认显示
     * @return false|string
     */
    public function textCutTextStr(string $str, int $length=0, bool $append=true)
    {
        return Common::shopCutStr($str, $length, $append);
    }

    /**
     * 文字截取具体到行数
     * @param string $textStr   要截取的字符串
     * @param int $rowNum       行数
     * @param int $wordNum      每行的文字书
     * @return string
     */
    public function textRowSubstr(string $textStr, int $rowNum, int $wordNum): string
    {
        $textArray = Common::cnRowSubstr($textStr, $rowNum, $wordNum);
        return $textArray[1] . ($textArray[2] ?? '');
    }
}